# -*- coding: utf-8 -*-
"""
二进制数据格式 实现数据的高效二进制格式存储最简单的方法之一是使用python 内置的pickle序列化  pandas对象都有一个用于将数据以pickle格式
报存到磁盘上的to_pickle方法

frame = pd.read_csv('../data/ex1.csv')
print(frame)

# 生成序列化
frame.to_pickle('../data/frame_pickle')

# 读取序列化
frame2 = pd.read_pickle('../data/frame_pickle')
print(frame2)

pandas 内置支持两个二进制数据格式 HDF5和MessagePack pandas或 Numpy数据的其他格式存储
bcolz：一种可压缩的列存储二进制格式，基于Blosc压缩库。
Feather：我与R语言社区的Hadley Wickham设计的一种跨语言的列存储文件格式。Feather使用了Apache Arrow的列式内存格式。

使用HDF5格式
HDF5是一种存储大规模科学数组数据的非常好的文件格式。HDF5中的HDF指的是层次型数据格式（hierarchical data format）。每个HDF5文件都含有一个文件系统式的节点结构，它使你能够存储多个数据集并支持元数据。与其他简单格式相比，HDF5支持多种压缩器的即时压缩，还能更高效地存储重复模式数据。对于那些非常大的无法直接放入内存的数据集，HDF5就是不错的选择，因为它可以高效地分块读写。

虽然可以用PyTables或h5py库直接访问HDF5文件，pandas提供了更为高级的接口，可以简化存储Series和DataFrame对象。HDFStore类可以像字典一样，处理低级的细节：

import numpy as np
import pandas as pd


# 创建一个DataFrame实例，包含100个随机数
frame1 = pd.DataFrame({'a':np.random.randn(100)}) # 生成100个随机数

# 打开或创建一个HDF5文件，用于存储大型数据
store = pd.HDFStore('../data/mydata.h5')

# 将DataFrame实例存储到HDF5文件中，键名为'obj1'
store['obj1'] = frame1

# 将DataFrame实例中的'a'列存储到HDF5文件中，键名为'obj1_col'
store['obj1_col'] = frame1['a']

# HDF5文件中的对象可以通过与字典一样的api进行获取
print(store.get('obj1'))

# HDFStore支持两种存储模式，'fixed'和'table'。后者通常会更慢，但是支持使用特殊语法进行查询操作：
# put是store.put方法的别名
store.put('obj2', frame1, format='table')

# 使用select方法和where参数进行查询操作，获取满足条件的数据
store.select('obj2', where=['index >= 10 and index <= 15'])

# 将DataFrame frame1保存到HDF5文件中，路径为/../data/mydata.h5，键名为'obj3'，使用表格式存储
frame1.to_hdf('../data/mydata.h5', 'obj3', format='table')

# 从HDF5文件中读取键名为'obj3'的数据，应用条件过滤，只选取索引小于5的行
pd.read_hdf('../data/mydata.h5', 'obj3', where=['index < 5'])

# 读取excel文件 可以使用扩展包 xlrd和openpyxl读取XLS和XLSX文件
# 使用ExcelFile 通过传递xls或xlsx路径创建一个实例
xlsx = pd.ExcelFile('../data/ex1.xlsx')

# 存储在表单中的数据可以通过read_excel方法读取到DataFrame实例中
frame = pd.read_excel(xlsx, 'Sheet1')

# 要读取一个文件中的多个表单 创建一个ExcelFile会更快,也可以将文件名传递给pandas.read_excel方法
frame2 = pd.read_excel('../data/ex1.xlsx', 'Sheet1')
print(frame2)

# 要将pandas数据写入EXcel格式 必须先创建一个ExcelWriter实例 然后使用pandas对象的to_excel方法将数据写入到writer实例中
writer = pd.ExcelWriter('../data/ex2.xlsx')
frame.to_excel(writer, 'Sheet1')
writer.save()

# 也可以不使用excelwriter而是传递文件的路径到to_excel方法
frame.to_excel('../data/ex2.xlsx')

import pandas as pd
import requests

# 许多网站都有一些通过json或其他格式提供数据的公共api 可以使用requests库从api中获取数据
url = 'https://api.github.com/repos/pandas-dev/pandas/issues'

resp = requests.get(url)
# 响应对象的json方法会返回一个包含被解析过的json字典 加载到一个python对象中
data = resp.json()
print(data[0]['title']) # 打印第一个issue的标题

# data中的每个元素都是一个包含所有GitHub 主题页数据的字典
issues = pd.DataFrame(data, columns=['number', 'title', 'labels', 'state'])
print(issues)

import sqlite3
import sqlalchemy as sqla

import pandas as pd
# 从dns.e164模块导入query模块 未使用
from dns.e164 import query

# 数据库交互 将数据从DataFrame对象写入数据库 使用SQLite数据库 模拟

# SQL语句 创建一个名为test的表，包含四个字段a, b, c, d
query = '''
CREATE TABLE test
(a VARCHAR(20) NOT NULL,
b VARCHAR(20),
c REAL,
d INTEGER);
'''

# 连接到SQLite数据库 如果数据库不存在则会自动创建一个
con = sqlite3.connect('mydata.sqlite')

# 执行SQL语句创建表
con.execute(query)

# 提交事务 确保更改被保存到数据库中
con.commit()

# 插入数据
# 定义将被插入到表中的数据元组列表 每个元组代表一行数据
data = [('Atlanta', 'Georgia', 1.25, 2000),
        ('Tallahassee', 'Florida', 2.6, 2010),
        ('Sacramento', 'California', 1.7, 2000)]

# 准备插入数据的SQL语句 ?作为占位符
stmt = "INSERT INTO test VALUES(?, ?, ?, ?)"

# 执行SQL语句，批量插入数据
con.executemany(stmt, data)

# 从表中读取数据 可以使用fetchone()方法获取一个数据行，fetchmany()方法获取多个数据行，fetchall()方法获取所有数据行 返回一个元组列表
cursor = con.execute('select * from test')

# 获取并打印表中的所有数据行
rows = cursor.fetchall()

print(rows)

# 将元组列表转换为DataFrame对象
# cursor.description 提供列的元数据，如列名
cursor.description

# 使用列名作为DataFrame的列名，创建DataFrame对象
pd.DataFrame(rows, columns=[x[0] for x in cursor.description])


# 可以使用 SQLAlchemy库来简化数据库操作 SQLAlchemy是一个ORM框架，它允许你使用Python对象和关系数据库进行交互
# pandas 有个read_sql函数 可以从 SQLAlchemy数据库连接中读取数据
# 创建数据库连接引擎
db = sqla.create_engine('sqlite:///mydata.sqlite')

# 从数据库中读取SQL查询结果
pd.read_sql('select * from test', db)

"""





if __name__ == '__main__':
    pass